#include<d3d9.h>
#include<d3dx9.h>
#include "ATGUI.h"
bool flag=true;
ATGUI::ATGUI(LPDIRECT3DDEVICE9 device, int w, int h)
{
	m_fonts = NULL;
	m_controls = NULL;
	m_vertexBuffers = NULL;
    stateflag=0;
	m_totalFonts = m_totalControls = m_totalBuffers = 0;
	m_windowWidth = m_windowHeight = 0;
	m_useBackDrop = false;
    flag=true;
	m_device = device;
	m_windowWidth = w; m_windowHeight = h;
	memset(&m_backDrop, 0, sizeof(stGUIControl));
}
bool ATGUI::AddBackdrop(char *fileName,float b_x, float b_y)
{
	if(!fileName) return false;

	m_backDrop.m_type = UGP_GUI_BACKDROP;

	// Load the texture image from file.
	if(D3DXCreateTextureFromFileA(m_device, fileName, &m_backDrop.m_backDrop) != D3D_OK)
		return false;

	// Get window width and height so we can create a fullscreen quad.
// 		float w = ((float)m_windowWidth/10)*4.1;
// 		float h = ((float)m_windowHeight/6)*4.0;
	float w = m_windowWidth;
	float h = m_windowHeight;

	stGUIVertex obj[] =
	{
		{w + b_x, 0 + b_y, 0.0f, 1, D3DCOLOR_XRGB(255,255,255), 1.0f, 0.0f},
		{w + b_x, h + b_y, 0.0f, 1, D3DCOLOR_XRGB(255,255,255), 1.0f, 1.0f},
		{0 + b_x, 0 + b_y, 0.0f, 1, D3DCOLOR_XRGB(255,255,255), 0.0f, 0.0f},
		{0 + b_x, h + b_y, 0.0f, 1, D3DCOLOR_XRGB(255,255,255), 0.0f, 1.0f},
	};
	m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	m_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	m_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	// Create the vertex buffer.
	if(FAILED(m_device->CreateVertexBuffer(sizeof(obj), 0, D3DFVF_GUI,
		D3DPOOL_DEFAULT, &m_backDropBuffer, NULL))) return false;

	// Fill the vertex buffer.
	void *ptr;
	if(FAILED(m_backDropBuffer->Lock(0, sizeof(obj), (void**)&ptr, 0))) return false;
	memcpy(ptr, obj, sizeof(obj));
	m_backDropBuffer->Unlock();

	m_useBackDrop = true;
    m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
	return true;
}

bool ATGUI::AddButton(int id, float x, float y)
{
	char *empty="empty.jpg";
	char *forward="forward.jpg";
	char *jump="jump.jpg";
	char *lamp="lamp.jpg";
	char *turnL="turnL.jpg";
	char *turnR="turnR.jpg";
	char *f1="f1.jpg";
	char *f2="f2.jpg";
	if(!empty || !forward || !jump) return false;

	if(!m_controls)
	{
		m_controls = new stGUIControl[1];
		if(!m_controls) return false;
		memset(&m_controls[0], 0, sizeof(stGUIControl));
	}
	else
	{
		stGUIControl *temp;
		temp = new stGUIControl[m_totalControls + 1];
		if(!temp) return false;
		memset(temp, 0, sizeof(stGUIControl) *
			(m_totalControls + 1));

		memcpy(temp, m_controls,
			sizeof(stGUIControl) * m_totalControls);

		delete[] m_controls;
		m_controls = temp;
	}

	// Set all the data needed to render/process a button.
	m_controls[m_totalControls].m_type = UGP_GUI_BUTTON;
	m_controls[m_totalControls].m_id = id;
	m_controls[m_totalControls].m_xPos = x;
	m_controls[m_totalControls].m_yPos = y;
	m_controls[m_totalControls].m_listID = m_totalBuffers;

	// Load the texture image from file.
	if(D3DXCreateTextureFromFileA(m_device, empty, &m_controls[m_totalControls].m_emptyTex) != D3D_OK)
	{
		return false;
	}

	if(D3DXCreateTextureFromFileA(m_device, forward, &m_controls[m_totalControls].m_forwardTex) != D3D_OK)
	{
		return false;
	}

	if(D3DXCreateTextureFromFileA(m_device, jump, &m_controls[m_totalControls].m_jumpTex) != D3D_OK)
	{
		return false;
	}
	if(D3DXCreateTextureFromFileA(m_device, lamp, &m_controls[m_totalControls].m_lampTex) != D3D_OK)
	{
		return false;
	}
	if(D3DXCreateTextureFromFileA(m_device, turnL, &m_controls[m_totalControls].m_turnLTex) != D3D_OK)
	{
		return false;
	}
	if(D3DXCreateTextureFromFileA(m_device, turnR, &m_controls[m_totalControls].m_turnRTex) != D3D_OK)
	{
		return false;
	}
	if(D3DXCreateTextureFromFileA(m_device, f1, &m_controls[m_totalControls].m_f1Tex) != D3D_OK)
	{
		return false;
	}
	if(D3DXCreateTextureFromFileA(m_device, f2, &m_controls[m_totalControls].m_f2Tex) != D3D_OK)
	{
		return false;
	}
	unsigned long white = D3DCOLOR_XRGB(255,255,255);

	// Get width and height of the image so we use that size.
	D3DSURFACE_DESC desc;
	m_controls[m_totalControls].m_emptyTex->GetLevelDesc(0, &desc);

	float w = ((float)desc.Width/3)*1.2;
	float h = ((float)desc.Height/3)*0.9;

	m_controls[m_totalControls].m_width = w;
	m_controls[m_totalControls].m_height = h;

	stGUIVertex obj[] =
	{
		{w + x, 0 + y, 0.0f, 1, white, 1.0f, 0.0f},
		{w + x, h + y, 0.0f, 1, white, 1.0f, 1.0f},
		{0 + x, 0 + y, 0.0f, 1, white, 0.0f, 0.0f},
		{0 + x, h + y, 0.0f, 1, white, 0.0f, 1.0f},
	};

	// Create the vertex buffer.
	if(!m_vertexBuffers)
	{
		m_vertexBuffers = new LPDIRECT3DVERTEXBUFFER9[1];
		if(!m_vertexBuffers) return false;
	}
	else
	{
		LPDIRECT3DVERTEXBUFFER9 *temp;
		temp = new LPDIRECT3DVERTEXBUFFER9[m_totalBuffers + 1];
		if(!temp) return false;

		memcpy(temp, m_vertexBuffers,
			sizeof(LPDIRECT3DVERTEXBUFFER9) * m_totalBuffers);

		delete[] m_vertexBuffers;
		m_vertexBuffers = temp;
	}

	if(FAILED(m_device->CreateVertexBuffer(sizeof(obj), 0,
		D3DFVF_GUI, D3DPOOL_DEFAULT, &m_vertexBuffers[m_totalBuffers], NULL)))
	{
		return false;
	}

	// Fill the vertex buffer.
	void *ptr;

	if(FAILED(m_vertexBuffers[m_totalBuffers]->Lock(0, sizeof(obj), (void**)&ptr, 0)))
	{
		return false;
	}

	memcpy(ptr, obj, sizeof(obj));
	m_vertexBuffers[m_totalBuffers]->Unlock();

	// Increase.
	m_totalBuffers++;

	// Increase.
	m_totalControls++;

	return true;
}
bool ATGUI::AddButton2(int id, float x, float y, char *up, char *over, char *down)
{
	if(!up || !over || !down) return false;

	if(!m_controls)
	{
		m_controls = new stGUIControl[1];
		if(!m_controls) return false;
		memset(&m_controls[0], 0, sizeof(stGUIControl));
	}
	else
	{
		stGUIControl *temp;
		temp = new stGUIControl[m_totalControls + 1];
		if(!temp) return false;
		memset(temp, 0, sizeof(stGUIControl) *
			(m_totalControls + 1));

		memcpy(temp, m_controls,
			sizeof(stGUIControl) * m_totalControls);

		delete[] m_controls;
		m_controls = temp;
	}

	// Set all the data needed to render/process a button.
	m_controls[m_totalControls].m_type = UGP_GUI_BUTTON2;
	m_controls[m_totalControls].m_id = id;
	m_controls[m_totalControls].m_xPos = x;
	m_controls[m_totalControls].m_yPos = y;
	m_controls[m_totalControls].m_listID = m_totalBuffers;

	// Load the texture image from file.
	if(D3DXCreateTextureFromFileA(m_device, up, &m_controls[m_totalControls].m_upTex) != D3D_OK)
	{
		return false;
	}

	if(D3DXCreateTextureFromFileA(m_device, over, &m_controls[m_totalControls].m_overTex) != D3D_OK)
	{
		return false;
	}

	if(D3DXCreateTextureFromFileA(m_device, down, &m_controls[m_totalControls].m_downTex) != D3D_OK)
	{
		return false;
	}

	unsigned long white = D3DCOLOR_XRGB(255,255,255);

	// Get width and height of the image so we use that size.
	D3DSURFACE_DESC desc;
	m_controls[m_totalControls].m_upTex->GetLevelDesc(0, &desc);

	float w = (float)desc.Width/2;
	float h = (float)desc.Height/2;

	m_controls[m_totalControls].m_width = w;
	m_controls[m_totalControls].m_height = h;

	stGUIVertex obj[] =
	{
		{w + x, 0 + y, 0.0f, 1, white, 1.0f, 0.0f},
		{w + x, h + y, 0.0f, 1, white, 1.0f, 1.0f},
		{0 + x, 0 + y, 0.0f, 1, white, 0.0f, 0.0f},
		{0 + x, h + y, 0.0f, 1, white, 0.0f, 1.0f},
	};

	// Create the vertex buffer.
	if(!m_vertexBuffers)
	{
		m_vertexBuffers = new LPDIRECT3DVERTEXBUFFER9[1];
		if(!m_vertexBuffers) return false;
	}
	else
	{
		LPDIRECT3DVERTEXBUFFER9 *temp;
		temp = new LPDIRECT3DVERTEXBUFFER9[m_totalBuffers + 1];
		if(!temp) return false;

		memcpy(temp, m_vertexBuffers,
			sizeof(LPDIRECT3DVERTEXBUFFER9) * m_totalBuffers);

		delete[] m_vertexBuffers;
		m_vertexBuffers = temp;
	}

	if(FAILED(m_device->CreateVertexBuffer(sizeof(obj), 0,
		D3DFVF_GUI, D3DPOOL_DEFAULT, &m_vertexBuffers[m_totalBuffers], NULL)))
	{
		return false;
	}

	// Fill the vertex buffer.
	void *ptr;

	if(FAILED(m_vertexBuffers[m_totalBuffers]->Lock(0, sizeof(obj), (void**)&ptr, 0)))
	{
		return false;
	}

	memcpy(ptr, obj, sizeof(obj));
	m_vertexBuffers[m_totalBuffers]->Unlock();

	// Increase.
	m_totalBuffers++;

	// Increase.
	m_totalControls++;

	return true;
}
void ATGUI::Shutdown()
{
	// Release all resources.

	if(m_useBackDrop)
	{
		if(m_backDrop.m_backDrop)
			m_backDrop.m_backDrop->Release();

		if(m_backDropBuffer)
			m_backDropBuffer->Release();
	}

	m_backDrop.m_backDrop = NULL;
	m_backDropBuffer = NULL;

	if(m_fonts) delete[] m_fonts;
	m_fonts = NULL;
	m_totalFonts = 0;

	for(int i = 0; i < m_totalBuffers; i++)
	{
		if(m_vertexBuffers[i])
		{
			m_vertexBuffers[i]->Release();
			m_vertexBuffers[i] = NULL;
		}
	}

	if(m_vertexBuffers) delete[] m_vertexBuffers;
	m_vertexBuffers = NULL;
	m_totalBuffers = 0;

	for(int i = 0; i < m_totalControls; i++)
	{
		if(m_controls[i].m_backDrop)
		{
			m_controls[i].m_backDrop->Release();
			m_controls[i].m_backDrop = NULL;
		}

		if(m_controls[i].m_emptyTex)
		{
			m_controls[i].m_emptyTex->Release();
			m_controls[i].m_emptyTex = NULL;
		}
		if(m_controls[i].m_forwardTex)
		{
			m_controls[i].m_forwardTex->Release();
			m_controls[i].m_forwardTex = NULL;
		}

		if(m_controls[i].m_jumpTex)
		{
			m_controls[i].m_jumpTex->Release();
			m_controls[i].m_jumpTex = NULL;
		}
		if(m_controls[i].m_lampTex)
		{
			m_controls[i].m_lampTex->Release();
			m_controls[i].m_lampTex = NULL;
		}
		if(m_controls[i].m_turnLTex)
		{
			m_controls[i].m_turnLTex->Release();
			m_controls[i].m_turnLTex = NULL;
		}
		if(m_controls[i].m_turnRTex)
		{
			m_controls[i].m_turnRTex->Release();
			m_controls[i].m_turnRTex = NULL;
		}
		if(m_controls[i].m_f1Tex)
		{
			m_controls[i].m_f1Tex->Release();
			m_controls[i].m_f1Tex = NULL;
		}
		if(m_controls[i].m_upTex)
		{
			m_controls[i].m_upTex->Release();
			m_controls[i].m_upTex = NULL;
		}
		if(m_controls[i].m_overTex)
		{
			m_controls[i].m_overTex->Release();
			m_controls[i].m_overTex = NULL;
		}
		if(m_controls[i].m_downTex)
		{
			m_controls[i].m_downTex->Release();
			m_controls[i].m_downTex = NULL;
		}
		if(m_controls[i].m_f2Tex)
		{
			m_controls[i].m_f2Tex->Release();
			m_controls[i].m_f2Tex = NULL;
		}
		if(m_controls[i].m_text)
		{
			delete[] m_controls[i].m_text;
			m_controls[i].m_text = NULL;
		}
	}

	if(m_controls) delete[] m_controls;
	m_controls = NULL;
	m_totalControls = 0;
}
void ATGUI:: ProcessGUI(ATGUI *gui, bool LMBDown, int mouseX, int mouseY, void(*funcPtr)(int id, int state))
{
	
	if(!gui) return;
     /*int stateflag=0;*/
	LPDIRECT3DDEVICE9 device = gui->GetDevice();
	if(!device) return;

	// Draw background.
	stGUIControl *backDrop = gui->GetBackDrop();
	LPDIRECT3DVERTEXBUFFER9 bdBuffer = gui->GetBackDropBuffer();

	// Only can draw if we have created it.
	if(gui->UseBackDrop() && backDrop && bdBuffer)
	{
		device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
		device->SetTexture(0, backDrop->m_backDrop);
		device->SetStreamSource(0, bdBuffer, 0, sizeof(stGUIVertex));
		device->SetFVF(D3DFVF_GUI);
		device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
		device->SetTexture(0, NULL);
	}

	// Objects used to display text.
	LPD3DXFONT pFont = NULL;
	RECT fontPosition = {0, 0, (long)gui->GetWindowWidth(),
		(long)gui->GetWindowHeight()};

	// Object used to render buttons;
	LPDIRECT3DVERTEXBUFFER9 pBuffer = NULL;
	int status = UGP_BUTTON_UP;

	// Loop through all controls and display them.
	for(int i = 0; i < gui->GetTotalControls(); i++)
	{
		// Get the current control.
		stGUIControl *pCnt = gui->GetGUIControl(i);
		if(!pCnt) continue;

		// Take action depending on what type it is.
		switch(pCnt->m_type)
		{
		case UGP_GUI_STATICTEXT:
			// Get font object this text uses.
			pFont = gui->GetFont(pCnt->m_listID);
			if(!pFont) continue;

			// Set text position.
			fontPosition.left = pCnt->m_xPos;
			fontPosition.top = pCnt->m_yPos;

			// Display text.
			//                   pFont->DrawText(NULL, pCnt->m_text, -1, &fontPosition,
			//                                   DT_LEFT, pCnt->m_color);
			break;
		case UGP_GUI_BUTTON:
			status = UGP_BUTTON_UP;

			// Get vertex buffer object this button uses.
			pBuffer = gui->GetVertexBuffer(pCnt->m_listID);
			if(!pBuffer) continue;

			// Set alpha transparency on for the texture image.
			device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
			device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
			device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

			// Check if we are over the button with the mouse or pressing it.
			if(mouseX > pCnt->m_xPos && mouseX < pCnt->m_xPos + pCnt->m_width &&
				mouseY > pCnt->m_yPos && mouseY < pCnt->m_yPos + pCnt->m_height)
			{
				if(LMBDown) {
					status = UGP_BUTTON_DOWN;
					if (flag==true)
					{
							stateflag+=1;
							flag=false;
							if (stateflag==8)
							{
								stateflag=0;
							}
					}
				
				}

				else status = UGP_BUTTON_OVER;
			}

			// Depending on the mouse state will depend on it's texture.
			if(status == UGP_BUTTON_UP) {
				if (stateflag==0)
				{
					device->SetTexture(0, pCnt->m_emptyTex);
					flag=true;
				}
				if (stateflag==1)
				{
					device->SetTexture(0, pCnt->m_forwardTex);
					flag=true;
				}
				if (stateflag==2)
				{
					device->SetTexture(0, pCnt->m_turnLTex);
					flag=true;
				}
				if (stateflag==3)
				{
					device->SetTexture(0, pCnt->m_turnRTex);
					flag=true;
				}
				if (stateflag==4)
				{
					device->SetTexture(0, pCnt->m_jumpTex);
					flag=true;
				}
				if (stateflag==5)
				{
					device->SetTexture(0, pCnt->m_lampTex);
					flag=true;
				}
				if (stateflag==6)
				{
					device->SetTexture(0, pCnt->m_f1Tex);
					flag=true;
				}
				if (stateflag==7)
				{
					device->SetTexture(0, pCnt->m_f2Tex);
					flag=true;
				}
				/*device->SetTexture(0, pCnt->m_upTex);*/
			}
			if(status == UGP_BUTTON_OVER) 
			{
				if (stateflag==0)
				{
					device->SetTexture(0, pCnt->m_emptyTex);
					flag=true;
				}
				if (stateflag==1)
				{
					device->SetTexture(0, pCnt->m_forwardTex);
					flag=true;
				}
				if (stateflag==2)
				{
					device->SetTexture(0, pCnt->m_turnLTex);
					flag=true;
				}
				if (stateflag==3)
				{
					device->SetTexture(0, pCnt->m_turnRTex);
					flag=true;
				}
				if (stateflag==4)
				{
					device->SetTexture(0, pCnt->m_jumpTex);
					flag=true;
				}
				if (stateflag==5)
				{
					device->SetTexture(0, pCnt->m_lampTex);
					flag=true;
				}
				if (stateflag==6)
				{
					device->SetTexture(0, pCnt->m_f1Tex);
					flag=true;
				}
				if (stateflag==7)
				{
					device->SetTexture(0, pCnt->m_f2Tex);
					flag=true;
				}
			}
			if(status == UGP_BUTTON_DOWN)
			{
				if (stateflag==0)
				{
					device->SetTexture(0, pCnt->m_emptyTex);
				}
				if (stateflag==1)
				{
					device->SetTexture(0, pCnt->m_forwardTex);
				}
				if (stateflag==2)
				{
					device->SetTexture(0, pCnt->m_turnLTex);
				}
				if (stateflag==3)
				{
					device->SetTexture(0, pCnt->m_turnRTex);
				}
				if (stateflag==4)
				{
					device->SetTexture(0, pCnt->m_jumpTex);
				}
				if (stateflag==5)
				{
					device->SetTexture(0, pCnt->m_lampTex);
				}
				if (stateflag==6)
				{
					device->SetTexture(0, pCnt->m_f1Tex);
				}
				if (stateflag==7)
				{
					device->SetTexture(0, pCnt->m_f2Tex);
				}
			}
			// Render button.
			device->SetStreamSource(0, pBuffer, 0, sizeof(stGUIVertex));
			device->SetFVF(D3DFVF_GUI);
			device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

			// Turn off alpha.
			device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
			break;
			case UGP_GUI_BUTTON2:
				status=UGP_BUTTON_UP;

				// Get vertex buffer object this button uses.
				pBuffer = gui->GetVertexBuffer(pCnt->m_listID);
				if(!pBuffer) continue;

				// Set alpha transparency on for the texture image.
				device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
				device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
				device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

				// Check if we are over the button with the mouse or pressing it.
				if(mouseX > pCnt->m_xPos && mouseX < pCnt->m_xPos + pCnt->m_width &&
					mouseY > pCnt->m_yPos && mouseY < pCnt->m_yPos + pCnt->m_height)
				{
					if(LMBDown) status = UGP_BUTTON_DOWN;
					else status = UGP_BUTTON_OVER;
				}

				// Depending on the mouse state will depend on it's texture.
				if(status == UGP_BUTTON_UP)
				{
					device->SetTexture(0, pCnt->m_upTex);
				}
				if(status == UGP_BUTTON_OVER)
				{
					device->SetTexture(0, pCnt->m_overTex);
				}
				if(status == UGP_BUTTON_DOWN) {
					device->SetTexture(0, pCnt->m_downTex);
				}
			// Render button.
			device->SetStreamSource(0, pBuffer, 0, sizeof(stGUIVertex));
			device->SetFVF(D3DFVF_GUI);
			device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

			// Turn off alpha.
			device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
			break;
		}

		// Process control by calling the callback function for it.
		if(funcPtr) funcPtr(pCnt->m_id, status);
	}
}